package com.heima.media.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.dto.ResponseResult;
import com.heima.common.minio.MinIOService;
import com.heima.common.util.SensitiveWordUtil;
import com.heima.media.dto.ArticleDto;
import com.heima.media.dto.ContentDto;
import com.heima.media.dto.ImageDto;
import com.heima.media.entity.WmChannel;
import com.heima.media.entity.WmNews;
import com.heima.media.entity.WmSensitive;
import com.heima.media.entity.WmUser;
import com.heima.media.feign.ArticleFeign;
import com.heima.media.service.*;
import org.apache.commons.io.IOUtils;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Service
public class IAuditServiceImpl implements IAuditService {
    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private ArticleFeign articleFeign;
    @Autowired
    @Lazy
    private IWmNewsService wmNewsService;
    @Autowired
    private MinIOService minIOService;
    @Autowired
    private IWmUserService wmUserService;
    @Autowired
    private IWmChannelService channelService;
    @Autowired
    private RedissonClient redissonClient;

    @Override
    @Async
    public void audit(WmNews news) {
        //阿里云文本审核
        boolean ispass = true;
        ispass = checkSensitive(news);
        if (!ispass) return;
        //阿里云图片审核
        ispass = checkImage(news);
        if (!ispass) return;
        //保存文章
        //判断现在的时间是不是到了发布时间
        if (System.currentTimeMillis() >= news.getPublishTime().getTime()) {
            Long saveAtticle = saveArticle(news);
            news.setArticleId(saveAtticle);
            news.setStatus(9);
        } else {
            news.setStatus(8);
            RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque("article-bqueue");
            RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
            //预期发布的时间-当前时间
            Long time = news.getPublishTime().getTime() - System.currentTimeMillis();
            delayedQueue.offer(news.getId(),time, TimeUnit.MILLISECONDS);
        }
        wmNewsService.updateById(news);
    }

    @Autowired
    private IWmSensitiveService sensitiveService;

    private boolean checkSensitive(WmNews wmNews) {
        String text = wmNews.getTitle();
        List<ContentDto> contentDtos = JSON.parseArray(wmNews.getContent(), ContentDto.class);
        for (ContentDto contentDto : contentDtos) {
            if (contentDto.getType().equals("text")) {
                text += contentDto.getValue();
            }
        }
        //构建一个DFA算法的Map
        List<WmSensitive> sensitiveList = sensitiveService.list();
        List<String> stringList = new ArrayList<>();
        for (WmSensitive wmSensitive : sensitiveList) {
            stringList.add(wmSensitive.getSensitives());
        }
        SensitiveWordUtil.initMap(stringList);
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(text);
        if (stringIntegerMap.size() > 0) {
            Set<String> strings = stringIntegerMap.keySet();
            String join = String.join(",", strings);
            wmNews.setStatus(2);
            wmNews.setReason("敏感词审核未通过，原因是包含以下敏感词：" + join);
            wmNewsService.updateById(wmNews);
            return false;
        } else {
            return true;
        }
    }
    @Override
    public Long saveArticle(WmNews news) {
        //根据wmnews,构建ArticleDto
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(news, articleDto);
        articleDto.setId(null);
        //app用户可以申请成为自媒体,自媒体用户就是文章作者
        //获取自媒体用户,自媒体用户中有AuthorId
        Integer userId = news.getUserId();
        WmUser wmUser = wmUserService.getById(userId);
        articleDto.setAuthorId(wmUser.getApAuthorId());
        articleDto.setAuthorName(wmUser.getName());
        articleDto.setChannelId(news.getChannelId());
        WmChannel wmChannel = channelService.getById(news.getChannelId());
        articleDto.setChannelName(wmChannel.getName());
        articleDto.setLayout(news.getType());
        articleDto.setFlag(0);
        List<ImageDto> imageDtoList = JSON.parseArray(news.getImages(), ImageDto.class);
        List<String> list = new ArrayList<>();
        for (ImageDto imageDto : imageDtoList) {
            list.add(imageDto.getUrl());
        }
        articleDto.setImages(JSON.toJSONString(list));
        ResponseResult<Long> longResponseResult = articleFeign.saveArticle(articleDto);
        Long resultData = longResponseResult.getData();
        return resultData;
    }

    private boolean checkImage(WmNews news) {
        boolean isPass = false;
        //图片包括:文章内容图片+文章的封面图片
        String newsImages = news.getImages();
        List<ImageDto> imageDtos = JSON.parseArray(newsImages, ImageDto.class);
        List<ContentDto> contentDtos = JSON.parseArray(news.getContent(), ContentDto.class);
        for (ContentDto contentDto : contentDtos) {
            if (contentDto.getType().equals("image")) {
                ImageDto imageDto = new ImageDto();
                imageDto.setId(contentDto.getId());
                imageDto.setUrl(contentDto.getValue());
                if (!imageDtos.contains(imageDto)) {
                    //判断是否有重复的,如果有就不再放进去
                    imageDtos.add(imageDto);
                }
            }
        }
        try {
            //imageDtos就是封面图片+内容图片
            List<byte[]> imageList = new ArrayList<>();
            for (ImageDto imageDto : imageDtos) {
                InputStream inputStream = minIOService.download(imageDto.getUrl());
                byte[] bytes = IOUtils.toByteArray(inputStream);
                imageList.add(bytes);
            }
            Map map = greenImageScan.imageScan(imageList);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion) {
                case "pass":
                    isPass = true;
                    break;
                case "review":
                    news.setStatus(3);
                    news.setReason("阿里云图片审核未通过，需要人工审核，原因是：" + map.get("label"));
                    wmNewsService.updateById(news);
                    isPass = false;
                    break;
                case "block":
                    news.setStatus(2);
                    news.setReason("阿里云图片审核未通过，原因是：" + map.get("label"));
                    wmNewsService.updateById(news);
                    isPass = false;
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isPass;
    }

    private boolean checkText(WmNews news) {
        //文中内容包括: 文章标题+文章内容
        String test = news.getTitle();
        List<ContentDto> contentDtos = JSON.parseArray(news.getContent(), ContentDto.class);
        for (ContentDto contentDto : contentDtos) {
            if (contentDto.getType().equals("text")) {
                test += contentDto.getValue();
            }
        }
        boolean isPass = false;
        try {
            Map map = greenTextScan.greenTextScan(test);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion) {
                case "pass":
                    isPass = true;
                    break;
                case "review":
                    news.setStatus(3);
                    news.setReason("阿里云文本审核未通过，需要人工审核，原因是：" + map.get("label"));
                    wmNewsService.updateById(news);
                    isPass = false;
                    break;
                case "block":
                    news.setStatus(2);
                    news.setReason("阿里云文本审核未通过，原因是：" + map.get("label"));
                    wmNewsService.updateById(news);
                    isPass = false;
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isPass;
    }
}
